Working with GDM models#
ERAD’s AssetSystem provides a class method for users working with a GDM DistributionSystem. Distribution system components are automatically mapped to the asset models and added to the AssetSystem. A hazard simulation can then be set up using the steps listed above. We start by loading a GDM model using the gdmloader package. This package can be installed using the command
pip install gdmloader
from IPython.display import display, HTML
import plotly.graph_objects as go
import plotly.io as pio
pio.renderers.default = "notebook_connected"
from gdm.distribution import DistributionSystem
from gdmloader.constants import GCS_CASE_SOURCE
from gdmloader.source import SystemLoader
gdm_loader = SystemLoader()
gdm_loader.add_source(GCS_CASE_SOURCE)
distribution_system: DistributionSystem = gdm_loader.load_dataset(
source_name=GCS_CASE_SOURCE.name,
system_type=DistributionSystem,
dataset_name="p1rhs7_1247",
version="2_1_2",
)
distribution_system.name = "p1rhs7_1247"
distribution_system.info()
System ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓ ┃ Property ┃ Value ┃ ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩ │ System name │ p1rhs7_1247 │ │ Data format version │ 2.1.4 │ │ Components attached │ 13370 │ │ Time Series attached │ 0 │ │ Description │ │ └──────────────────────┴─────────────┘
Component Information ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Type ┃ Count ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ DistributionBus │ 2510 │ │ DistributionLoad │ 1896 │ │ DistributionTransformer │ 503 │ │ DistributionTransformerEquipment │ 10 │ │ DistributionVoltageSource │ 1 │ │ LoadEquipment │ 1896 │ │ Location │ 2510 │ │ MatrixImpedanceBranch │ 1841 │ │ MatrixImpedanceBranchEquipment │ 38 │ │ MatrixImpedanceFuse │ 81 │ │ MatrixImpedanceFuseEquipment │ 6 │ │ MatrixImpedanceSwitch │ 84 │ │ MatrixImpedanceSwitchEquipment │ 15 │ │ PhaseLoadEquipment │ 1948 │ │ PhaseVoltageSourceEquipment │ 3 │ │ TimeCurrentCurve │ 1 │ │ VoltageLimitSet │ 8 │ │ VoltageSourceEquipment │ 1 │ │ WindingEquipment │ 18 │ └──────────────────────────────────┴───────┘
Next, we built the asset system from the gdm DistributionSystem using the from_gdm method.
from erad.systems import AssetSystem
asset_system = AssetSystem.from_gdm(distribution_system)
asset_system.info()
for a in asset_system.iter_all_components():
a.pprint()
break
System ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Property ┃ Value ┃ ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ System name │ │ │ Data format version │ │ │ Components attached │ 4987 │ │ Time Series attached │ 0 │ │ Description │ │ └──────────────────────┴───────┘
Component Information ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Type ┃ Count ┃ ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ Asset │ 4987 │ └──────────────────────┴───────┘
Downloading N38W123.hgt.zip
Asset( name='sb10_p1rhs7_1247_bus_10_6', distribution_asset=UUID('1f95b063-9b69-4331-8f56-6a718161087f'), connections=[], devices=[], asset_type=<AssetTypes.distribution_poles: 6>, height=<Quantity(0.0, 'meter')>, latitude=38.64000605387684, longitude=-122.50715315149552, asset_state=[], elevation=<Quantity(460.0, 'meter')> )
Plotting an AssetSystem#
fig = asset_system.plot(show=False)
display(HTML(pio.to_html(fig, include_plotlyjs="cdn", full_html=False)))
Building a HazardModel#
In this section, we built a hazard model and apply the model the asset system.
from datetime import datetime
from shapely.geometry import Polygon
from gdm.quantities import Distance
from erad.models.hazard import FloodModelArea, FloodModel
from erad.systems import HazardSystem
from erad.quantities import Speed
flood_area = FloodModelArea(
affected_area=Polygon(
[
(-122.38, 38.70),
(-122.35, 38.68),
(-122.343, 38.69),
(-122.37, 38.7035),
]
),
water_velocity=Speed(0, "meter/second"),
water_elevation=Distance(160, "meter"),
)
flood = FloodModel(
name="flood 1",
timestamp=datetime.now(),
affected_areas=[flood_area],
)
user_defined_flood_event = HazardSystem(auto_add_composed_components=True)
user_defined_flood_event.add_component(flood)
Overlaying the HazardModel#
We can overlay the hazard model on the same plot using the add_trace method. The show method can be used to render the image again.
polygon = flood.affected_areas[0].affected_area
lon, lat = polygon.exterior.xy # returns x and y sequences
fig.add_trace(
go.Scattermap(
fill="toself",
lon=lon.tolist(),
lat=lat.tolist(),
marker={"size": 10, "color": flood.affected_areas[0].water_velocity.magnitude},
)
)
fig.show()
Finally, we can run the actual simulation using the HazardSimulator class from erad.runner.
from erad.runner import HazardSimulator
user_defined_flood_event.info()
hazard_scenario = HazardSimulator(asset_system=asset_system)
hazard_scenario.run(hazard_system=user_defined_flood_event)
System ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Property ┃ Value ┃ ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ System name │ │ │ Data format version │ │ │ Components attached │ 2 │ │ Time Series attached │ 0 │ │ Description │ │ └──────────────────────┴───────┘
Component Information ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓ ┃ Type ┃ Count ┃ ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩ │ FloodModel │ 1 │ │ FloodModelArea │ 1 │ └──────────────────────┴───────┘
2025-09-08 20:28:15.136 | WARNING | erad.runner:run:52 - No HazardFragilityCurves definitions found in the passed HazardSystem, using default curve definitions
2025-09-08 20:28:15.136 | INFO | erad.runner:run:60 - Simulating hazard at 2025-09-08 20:28:15.007362
Once the simulation is complete, we can visualize the results by plotting the survival_prob from the updated gdf dataframe.
fig = asset_system.plot(show=False)
display(HTML(pio.to_html(fig, include_plotlyjs="cdn", full_html=False)))